package com.example.checkqufuface.View.QufuFaceProject;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.example.checkqufuface.Base.BaseActivity;
import com.example.baselibrary.Interface.FacePickInterface;
import com.example.baselibrary.Utils.Customer;
import com.example.baselibrary.Utils.FaceCj;
import com.example.baselibrary.Utils.FaceMasks;
import com.example.baselibrary.Utils.LogUtil;
import com.example.baselibrary.Utils.MyBitmapUtils;
import com.example.baselibrary.Utils.OutFace;
import com.example.checkqufuface.Utils.SelfToastUtil;
import com.example.baselibrary.Utils.StringUtil;
import com.example.checkqufuface.R;
import com.example.checkqufuface.RetrufitHelp.BaseSubscriber;
import com.example.checkqufuface.RetrufitHelp.ExceptionHandle;
import com.example.checkqufuface.RetrufitHelp.RetrofitClient;
import com.example.checkqufuface.bean.QuFuOrderBindFaceRequsetBean;
import com.example.checkqufuface.bean.QufuCollectSaleTicketRequsetBean;
import com.example.checkqufuface.bean.QufuCollectSaleTicketResultBean;
import com.example.checkqufuface.bean.QufuQueryStaffReceiveTicketResultBean;
import com.example.checkqufuface.bean.QufuimageStrUploadRequsetBean;
import com.example.checkqufuface.bean.QufuimageStrUploadResultBean;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

public class FaceSaveActivity extends BaseActivity implements SurfaceHolder.Callback, Camera.PreviewCallback {


    private String scenicTicketId;
    private String name;
    private String sex;
    private String type;
    private String number;
    private String phone;

    SurfaceView svPreview;
    private Camera mCamera;
    private int width = 1280;
    private int height = 720;

    private HandlerThread handleThread;
    private Handler detectHandler;

    private Bitmap bitmap;
    private Bitmap bitmap1;
    private Bitmap bitmap_collect;
    private static String basa64;
    private TextView tvTipShow;
    private ImageView ivTipFace;
    ImageView m_ivFace;
    private FaceMasks fmMask;
    private Button pickAgain;
    private Button takePhoto;
    private Button back;
    private Button confim;
    private boolean goToTackPhoto = false;

    private LinearLayout llTipResult;

    private Timer timer = null;//计时器
    private TimerTask timerTask = null;
    private int i = 3;

    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            if (msg.arg1 <= 0) {
                finish();
            } else {
                startTime();
            }
        }

        ;
    };
    private TextView tvSuccess;
    private String certificateNo;
    private String comeFrom;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        name = intent.getStringExtra("name");
        sex = intent.getStringExtra("sex");
        type = intent.getStringExtra("type");
        number = intent.getStringExtra("number");
        phone = intent.getStringExtra("phone");
        scenicTicketId = intent.getStringExtra("scenicTicketId");

        certificateNo = intent.getStringExtra("certificateNo");
        comeFrom = intent.getStringExtra("ComeFrom");
    }

    @Override
    protected int getView() {
        return R.layout.activity_face_save;

    }

    @Override
    public void init() {
        svPreview = (SurfaceView) findViewById(R.id.sv_preview_track_qufu);
        tvTipShow = findViewById(R.id.tv_title_result);
        ivTipFace = findViewById(R.id.iv_title_face);
        m_ivFace = (ImageView) findViewById(R.id.iv_face);
        fmMask = (FaceMasks) findViewById(R.id.fm_mask_track);

        pickAgain = findViewById(R.id.bt_pick_again);
        takePhoto = findViewById(R.id.bt_take_photo);
        back = findViewById(R.id.bt_back);
        confim = findViewById(R.id.bt_confrim);

        llTipResult = findViewById(R.id.ll_title_result);
        tvSuccess = findViewById(R.id.tv_success_show);


        pickAgain.setVisibility(View.VISIBLE);
        takePhoto.setVisibility(View.VISIBLE);
        back.setVisibility(View.VISIBLE);
        confim.setVisibility(View.VISIBLE);
        tvSuccess.setVisibility(View.GONE);

        svPreview.getWidth();
        svPreview.getHeight();

        //初始化人脸资源

        //初始化摄像头
        handleThread = new HandlerThread("dt");
        handleThread.start();
        detectHandler = new Handler(handleThread.getLooper());
        svPreview.getHolder().addCallback(this);
        svPreview.setKeepScreenOn(true);


        FaceCj.SetFaceRectListener(new FacePickInterface() {
            @Override
            public void getFace(final RectF f) {
                fmMask.setFacePar(f);
            }

            @Override
            public void noFace() {
                fmMask.setFacePar(new RectF());
            }
        });

        FaceMasks.setOutFaceListener(new OutFace() {
            @Override
            public void faceOut() {
                //如果超出边框 那么就提示 并且不截图
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
//                        SelfToastUtil.getInstance().show("请将人脸至于绿框内");
//                        tvTipShow.setText("无法捕捉到人脸，请将人脸至于绿框内");
                    }
                });

            }
        });

        doThings();


    }

    private void doThings() {

        pickAgain.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                m_ivFace.setImageResource(R.mipmap.facebgs);
            }
        });
        takePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                goToTackPhoto = true;
            }
        });

        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        confim.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //  确认 那么就去网络请求了
//                SelfToastUtil.getInstance().show("去保存照片");
                GoToUpAndSaveImage();
            }
        });

    }

    /**
     * 开始自动减时
     */
    private void startTime() {
        if (timer == null) {
            timer = new Timer();
        }

        timerTask = new TimerTask() {

            @Override
            public void run() {
                i--;//自动减1
                Message message = Message.obtain();
                message.arg1 = i;
                mHandler.sendMessage(message);//发送消息
            }
        };
        timer.schedule(timerTask, 1000);//1000ms执行一次
    }

    private void GoToUpAndSaveImage() {
        QufuimageStrUploadRequsetBean strUploadRequsetBean = new QufuimageStrUploadRequsetBean();
        if (StringUtil.isNullOrEmpty(basa64)) {
            SelfToastUtil.getInstance().show("请先进行人脸拍照");
            return;
        }
        strUploadRequsetBean.setImageStr(basa64);
        RetrofitClient.getInstance(FaceSaveActivity.this, BASE_URL, headers).imageStrUpload(strUploadRequsetBean, new BaseSubscriber<QufuimageStrUploadResultBean>(FaceSaveActivity.this) {
            @Override
            public void onError(ExceptionHandle.ResponeThrowable e) {
                SelfToastUtil.getInstance().show(e.message);
            }

            @Override
            public void onNext(QufuimageStrUploadResultBean qufuimageStrUploadResultBean) {
                String code = qufuimageStrUploadResultBean.getCode();
                if (code.equals("200")) {
                    // 上传成功后 观察来源，然后进行不同的操作
                    String filePath = qufuimageStrUploadResultBean.getData().get(0).getFilePath();
                    if ((!StringUtil.isNullOrEmpty(comeFrom)) && comeFrom.equals("FacePickActivity")) {
                        //曲阜 人脸采集   人脸补录
                        queryStaffReceiveTicket(filePath);
                    } else {
                        //曲阜 采集人脸购票
                        peopleFaceCollectSaleTicket(filePath);
                    }
                } else {
                    SelfToastUtil.getInstance().show(qufuimageStrUploadResultBean.getMessage());
                }
            }
        });
    }

    private void queryStaffReceiveTicket(String filePath) {
        QuFuOrderBindFaceRequsetBean orderBindFaceRequsetBean = new QuFuOrderBindFaceRequsetBean();

        orderBindFaceRequsetBean.setFacePicPath(filePath);
        orderBindFaceRequsetBean.setCertificateNo(certificateNo);

        RetrofitClient.getInstance(FaceSaveActivity.this, BASE_URL, headers).orderBindFace(orderBindFaceRequsetBean, new BaseSubscriber<QufuQueryStaffReceiveTicketResultBean>(FaceSaveActivity.this) {
            @Override
            public void onError(ExceptionHandle.ResponeThrowable e) {
                SelfToastUtil.getInstance().show(e.message);
            }

            @Override
            public void onNext(QufuQueryStaffReceiveTicketResultBean qufuQueryStaffReceiveTicketResultBean) {
                String code = qufuQueryStaffReceiveTicketResultBean.getCode();
                if (code.equals("200")) {
                    //  3 秒后 退出界面
                    //保存成功，要清除数据
                    basa64 = null;
                    startTime();
                    ShowSuccessFace();
                } else {
                    SelfToastUtil.getInstance().show(qufuQueryStaffReceiveTicketResultBean.getMessage());
                }
            }
        });
    }

    private void peopleFaceCollectSaleTicket(String filePath) {
        QufuCollectSaleTicketRequsetBean saleTicketRequsetBean = new QufuCollectSaleTicketRequsetBean();
        saleTicketRequsetBean.setScenicTicketId(scenicTicketId);
        saleTicketRequsetBean.setCertificateName(name);
        saleTicketRequsetBean.setCertificateNo(number);
        saleTicketRequsetBean.setCertificateTypeId(type);
        saleTicketRequsetBean.setGender(sex);
        saleTicketRequsetBean.setPhoneNumber(phone);
        saleTicketRequsetBean.setPhotoPath(filePath);
        RetrofitClient.getInstance(FaceSaveActivity.this, BASE_URL, headers).peopleFaceCollectSaleTicket(saleTicketRequsetBean, new BaseSubscriber<QufuCollectSaleTicketResultBean>(FaceSaveActivity.this) {
            @Override
            public void onError(ExceptionHandle.ResponeThrowable e) {
                SelfToastUtil.getInstance().show(e.message);
            }

            @Override
            public void onNext(QufuCollectSaleTicketResultBean qufuCollectSaleTicketResultBean) {
                String code = qufuCollectSaleTicketResultBean.getCode();
                if (code.equals("200")) {
                    //  3 秒后 退出界面
                    //保存成功，要清除数据
                    basa64 = null;
                    startTime();
                    ShowSuccessFace();
                } else {
                    SelfToastUtil.getInstance().show(qufuCollectSaleTicketResultBean.getMessage());
                }
            }
        });
    }

    private void ShowSuccessFace() {

        pickAgain.setVisibility(View.GONE);
        takePhoto.setVisibility(View.GONE);
        back.setVisibility(View.GONE);
        confim.setVisibility(View.GONE);
        tvSuccess.setVisibility(View.VISIBLE);

        llTipResult.setBackgroundColor(getResources().getColor(R.color.color_green));
        tvTipShow.setText("采集成功");
        tvTipShow.setTextColor(getResources().getColor(R.color.color_duck_green));
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        try {
            mCamera = Camera.open(0);
            mCamera.setDisplayOrientation(90);
            Camera.Parameters para = mCamera.getParameters();

            Point showingArea = new Point();
            WindowManager wm = (WindowManager) getSystemService(
                    Context.WINDOW_SERVICE);
            Display display = wm.getDefaultDisplay();
            int screenWidth = display.getWidth();
            int screenHeight = display.getHeight();

            int topHeight = dip2px(FaceSaveActivity.this, 25 + 44);//状态栏+titlebar
            showingArea.set(screenWidth, screenHeight - topHeight);

            width = 640;
            height = 480;
            // 预览变形的问题
            Log.e("size", "size w:" + width + "--h:" + height);

            para.setPreviewSize(width, height);
            mCamera.setParameters(para);
        } catch (Exception e) {
//            ToastUtil.showToast("无法找到摄像头，请确定摄像头已连接");
            SelfToastUtil.getInstance().show("无法找到摄像头，请确定摄像头已连接");
        }

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        if (mCamera == null) {
            return;
        }
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.setDisplayOrientation(90);
            mCamera.startPreview();
            mCamera.setPreviewCallback(this);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

        if (mCamera == null) {
            return;
        }
        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }


    @Override
    public void onPreviewFrame(byte[] data, final Camera camera) {

        // 这个方法 让数据方向进行调整
        final byte[] datas = rotateYUV420Degree180(data, width, height);

        camera.setPreviewCallback(null);
        if (mCamera == null) return;
        detectHandler.post(new Runnable() {
            @Override
            public void run() {
                coseToBase64(datas, camera);
                try {
                    camera.setPreviewCallback(FaceSaveActivity.this);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }


        });
    }


    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    private byte[] rotateYUV420Degree180(byte[] data, int imageWidth, int imageHeight) {
        byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
        int i = 0;
        int count = 0;
        for (i = imageWidth * imageHeight - 1; i >= 0; i--) {
            yuv[count] = data[i];
            count++;
        }
        i = imageWidth * imageHeight * 3 / 2 - 1;
        for (i = imageWidth * imageHeight * 3 / 2 - 1; i >= imageWidth
                * imageHeight; i -= 2) {
            yuv[count++] = data[i - 1];
            yuv[count++] = data[i];
        }
        return yuv;
    }

    //这个方法处理图片 后期需要放在 子线程里面
    private void coseToBase64(byte[] data, Camera camera) {

        try {
            Camera.Size previewSize = camera.getParameters().getPreviewSize();//获取尺寸,格式转换的时候要用到
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            newOpts.inJustDecodeBounds = true;
            YuvImage yuvimage = new YuvImage(
                    data,
                    ImageFormat.NV21,
                    previewSize.width,
                    previewSize.height,
                    null);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 100, baos);// 80--JPG图片的质量[0-100],100最高
            final byte[] rawImage = baos.toByteArray();
//        将rawImage转换成bitmap
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.ARGB_8888;

            bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options);

            if (bitmap != null) {
                bitmap1 = MyBitmapUtils.rotateBitmap(bitmap, 270, false);
            }

            //经过测试  bitmap1，不为空的情况下，bitmap_collect为空，是剪裁里面 检查不到人脸，返回为空
            if (bitmap1 != null) {
                bitmap_collect = FaceCj.cutFace(bitmap1, FaceSaveActivity.this);

            }


            if (bitmap_collect != null) {

//                runOnUiThread(new Runnable() {
//                    @Override
//                    public void run() {
//                        tvTipShow.setText("人脸出现，请点击拍照");
//                    }
//                });
                if (goToTackPhoto) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            m_ivFace.setImageBitmap(bitmap_collect);
                            basa64 = MyBitmapUtils.bitmapToBase64(bitmap_collect);
                            goToTackPhoto = false;
                        }
                    });
                }

                MyBitmapUtils.saveBitmap(bitmap_collect, new File(Environment.getExternalStorageDirectory().toString() + File.separator + Customer.FOLDER_NAME + File.separator + "zyfqufu.png"));
            }
        } catch (Exception e) {
            LogUtil.v("图片回收异常");
        }
    }


}
